package cn.jpush.api.push.model;

import cn.jiguang.common.DeviceType;
import cn.jiguang.common.utils.Preconditions;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;

import java.util.HashSet;
import java.util.Set;

public class Platform implements PushModel {
    private static final String ALL = "all";

    private final boolean all;
    private final Set<DeviceType> deviceTypes;

    private Platform(boolean all, Set<DeviceType> deviceTypes) {
        this.all = all;
        this.deviceTypes = deviceTypes;
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public static Platform all() {
        return newBuilder().addDeviceType(DeviceType.Android).addDeviceType(DeviceType.IOS).addDeviceType(DeviceType.Windows).addDeviceType(DeviceType.Web).build();
    }

    public static Platform android() {
        return newBuilder().addDeviceType(DeviceType.Android).build();
    }

    public static Platform ios() {
        return newBuilder().addDeviceType(DeviceType.IOS).build();
    }

    public static Platform winphone() {
        return newBuilder().addDeviceType(DeviceType.WinPhone).build();
    }

    public static Platform android_ios() {
        return newBuilder()
                .addDeviceType(DeviceType.Android)
                .addDeviceType(DeviceType.IOS)
                .build();
    }

    public static Platform android_winphone() {
        return newBuilder()
                .addDeviceType(DeviceType.Android)
                .addDeviceType(DeviceType.WinPhone)
                .build();
    }

    public static Platform ios_winphone() {
        return newBuilder()
                .addDeviceType(DeviceType.IOS)
                .addDeviceType(DeviceType.WinPhone)
                .build();
    }

    public static Platform windows() {
        return newBuilder().addDeviceType(DeviceType.Windows).build();
    }

    public static Platform web() {
        return newBuilder().addDeviceType(DeviceType.Web).build();
    }

    public static Platform android_windows() {
        return newBuilder().addDeviceType(DeviceType.Android).addDeviceType(DeviceType.Windows).build();
    }

    public static Platform android_web() {
        return newBuilder().addDeviceType(DeviceType.Android).addDeviceType(DeviceType.Web).build();
    }

    public static Platform android_ios_windows() {
        return newBuilder().addDeviceType(DeviceType.Android).addDeviceType(DeviceType.IOS).addDeviceType(DeviceType.Windows).build();
    }

    public static Platform android_ios_web() {
        return newBuilder().addDeviceType(DeviceType.Android).addDeviceType(DeviceType.IOS).addDeviceType(DeviceType.Web).build();
    }

    public static Platform android_windows_web() {
        return newBuilder().addDeviceType(DeviceType.Android).addDeviceType(DeviceType.Windows).addDeviceType(DeviceType.Web).build();
    }

    public static Platform ios_windows_web() {
        return newBuilder().addDeviceType(DeviceType.IOS).addDeviceType(DeviceType.Windows).addDeviceType(DeviceType.Web).build();
    }

    public static Platform ios_windows() {
        return newBuilder().addDeviceType(DeviceType.IOS).addDeviceType(DeviceType.Windows).build();
    }

    public static Platform ios_web() {
        return newBuilder().addDeviceType(DeviceType.IOS).addDeviceType(DeviceType.Web).build();
    }

    public static Platform windows_web() {
        return newBuilder().addDeviceType(DeviceType.Windows).addDeviceType(DeviceType.Web).build();
    }

    public boolean isAll() {
        return all;
    }

    @Override
    public JsonElement toJSON() {
        if (all) {
            return new JsonPrimitive(ALL);
        }

        JsonArray json = new JsonArray();
        for (DeviceType deviceType : deviceTypes) {
            json.add(new JsonPrimitive(deviceType.value()));
        }
        return json;
    }

    public boolean contains(DeviceType deviceType) {
        if (this.all) {
            return true;
        }
        return this.deviceTypes.contains(deviceType);
    }

    public static class Builder {
        private boolean all;
        private Set<DeviceType> deviceTypes;

        public Builder setAll(boolean all) {
            this.all = all;
            return this;
        }

        public Builder addDeviceType(DeviceType deviceType) {
            if (null == deviceTypes) {
                deviceTypes = new HashSet<DeviceType>();
            }
            deviceTypes.add(deviceType);
            return this;
        }

        public Platform build() {
            Preconditions.checkArgument(!(all && null != deviceTypes), "Since all is enabled, any platform should not be set.");
            Preconditions.checkArgument(!(!all && null == deviceTypes), "No any deviceType is set.");
            return new Platform(all, deviceTypes);
        }
    }

}


